// void, Obj This

Hero this;
Obj u;
Unit ua;
ObjList where_the_battle1;
point ptStart;
bool bSquadTarget;
int i, rcount;

Sleep(rand(20)+30);
this = This.AsHero;
ptStart = .pos;

//pr("hero::engage: looking for enemies");
rcount = 0;
for(i=0; i<.army.count; i+=1){
	
	ua = .army[i].AsUnit;
	if(ua.IsValid){
		if(ua.IsRanged)
			rcount+=1;
	}
}
if(rcount > 0) rcount = 8*rcount;

while(.IsValid){
        
	//pr("engage");
	bSquadTarget = false;
	
	if (.IsEnemyInSquadSight()){
	
		//u = .BestTargetInSquadSight();
		u = .BestTargetInRange( .posRH, 60 );
		
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInRange( .posRH, 120 );
			
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInRange( .posRH, 240 );
			
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInRange( .posRH, 480 );
			
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInSquadSight();
			
		if(u.IsAlive()){
			if(u.AsUnit.hero.IsValid)
				if(u.AsUnit.hero.command == "retreat_notai" ||
					u.AsUnit.hero.command == "retreat_bld_notai")
					break;
			if(.IsValidTarget(u))
			if(.DistTo(u.pos) > .min_range)
				if(.DistTo(u.pos) < (300+rcount))
					if(u.IsMilitary || u.IsHeirOf("Catapult"))
						if(u.AsUnit.command != "retreat_notai" &&
							u.AsUnit.hero.command != "retreat_bld_notai")
							bSquadTarget = true;
		}
		
		for (i=0; !bSquadTarget && i<.army.count; i+=1){
		
			ua = .army[i].AsUnit;
			u = .army[i].AsUnit.BestTargetInSquadSight();
			
			if(u.IsAlive())
				if(.IsValidTarget(u))
				if(.DistTo(u.pos) > .min_range)
					if(ua.DistTo(u.pos) < (200+rcount))
						if(u.IsMilitary || u.IsHeirOf("Catapult"))
							if(u.AsUnit.command != "retreat_notai" &&
								u.AsUnit.hero.command != "retreat_bld_notai")
								bSquadTarget = true;
		}		
	}
	//pr(bSquadTarget);
	if(!bSquadTarget)
		break; // there is no enemy we could fight
	
	.army.ClearDead;	
	for(i=0; i<.army.count; i+=1){
		if(.army[i].IsMilitary){
			if(.DistTo(.army[i].pos) < 620){
				if(.army[i].command != "engage" 
				&& .army[i].command != "approach_hero"
				&& .army[i].command != "getitems"){
					Sleep(rand(20)+30);
					.army[i].SetCommand("engage");
				}
			} else {
				if(.army[i].command == "stand_position"){
					Sleep(rand(20)+30);
					.army[i].SetCommand("engage");		
				}
			}
		} else if(.army[i].IsHeirOf("BaseMage")){
			if(.army[i].command != "idle"){
				Sleep(rand(20)+30);
				.army[i].SetCommand("idle");		
			}
		}
		Sleep(5);
	}
        
                
	if(!u.IsAlive()){
		Sleep(417);
	}
	while(u.IsAlive()){
		//pr("hero::engage: chasing");
		while(!.GotoAttack(u, 1500, false, 15000)){
			//pr("hero::engage: proba podejscia");
			if(!u.IsValid || !.IsValidTarget(u))
				u = .BestTargetInRange( .posRH, 120 );
			
			if(!u.IsValid || !.IsValidTarget(u))
				u = .BestTargetInRange( .posRH, 240 );
				
			if(!u.IsValid || !.IsValidTarget(u))
				u = .BestTargetInRange( .posRH, 480 );
			
			if(!u.IsValid || !.IsValidTarget(u))
				u = .BestTargetInSquadSight();
			
			if(!u.IsAlive) 
				break;
			if(!.IsValidTarget(u)) 
				break;
			if(.DistTo(u.pos) < .min_range) 
				break;
			if(!u.IsMilitary)
				break;
			if(.DistTo(ptStart) > 700)
				break;
			if(u.AsUnit.hero.IsValid)
				if(u.AsUnit.hero.command == "retreat_notai" ||
					u.AsUnit.hero.command == "retreat_bld_notai")
					break;
		}

		//.pr("hero::engage: fighting");
		if(u.IsAlive)
			if(.IsValidTarget(u))
			if(.DistTo(u.pos) > .min_range)
				if(u.IsMilitary || u.IsHeirOf("Catapult"))
					if(u.AsUnit.hero.IsValid){
						if(u.AsUnit.hero.command != "retreat_notai" &&
							u.AsUnit.hero.command != "retreat_bld_notai")
							while(.Attack(u));
					} else while(.Attack(u));

		//if (GetTime - nStartTime > 1000) break;

		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInRange( .posRH, 120 );
			
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInRange( .posRH, 240 );
			
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInRange( .posRH, 480 );
				
		if(!u.IsValid || !.IsValidTarget(u))
			u = .BestTargetInSquadSight();
		
		if(!u.IsAlive)	
			break;
		if(!.IsValidTarget(u))	
			break;
		if(.DistTo(u.pos) < .min_range) 
			break;
		if(!u.IsMilitary && !u.IsHeirOf("Catapult"))
			break;
		if(.DistTo(ptStart) > 700) 
			break;
		if(u.AsUnit.hero.IsValid)
			if(u.AsUnit.hero.command == "retreat_notai" ||
				u.AsUnit.hero.command == "retreat_bld_notai")
				break;
			
	}
	
	while(!.Stop(1000));
	//.pr("hero::engage: enemies killed");

}

Sleep(300+rand(300)); // Else the sneak command cycles, because of the delayed update of enemies in 'BestTargetInSquadSight'
